<!DOCTYPE html>
<html>
  



<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
  <!-- Global site tag (gtag.js) - Google Analytics -->


  <title>使用hexo+github搭建免费个人博客详细教程 | 😄豐Dの个人博客</title>

  
    
<link rel="stylesheet" href="/js/aos/aos.css">

  

  <link rel="icon" type="image/x-icon, image/vnd.microsoft.icon" href="/favicon.ico">
  <link rel="stylesheet" href="https://at.alicdn.com/t/font_1911880_c1nvbyezg17.css">
  <link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">

  
    <script>
        var themeModelId = '';
        if (themeModelId) {
            localStorage.setItem('modelId', themeModelId);
        }
    </script>
    
    <script src="https://cdn.jsdelivr.net/gh/yuang01/live2d-widget@latest/autoload.js"></script>
    <script>
        var live2dOpen = eval('true') || false;
        if (!live2dOpen) {
            localStorage.setItem('waifu-display', 1609323474481);
        }
    </script>
  
  
<link rel="stylesheet" href="/css/animate.min.css">

  
<link rel="stylesheet" href="/css/style.css">

  
  
    
<link rel="stylesheet" href="/js/fancybox/jquery.fancybox.min.css">

  
  
  <style>
        @media (max-width: 992px) {
            #waifu {
                display: none;
            }
        }
    </style>
    <script src="//cdn.bootcss.com/pace/1.0.2/pace.min.js"></script>
    <link href="//cdn.bootcss.com/pace/1.0.2/themes/pink/pace-theme-flash.css" rel="stylesheet">
<meta name="generator" content="Hexo 5.3.0"></head>

  <script src="/js/jquery3.5.1.js"></script>
  <script src="/js/vue2.6.11.js"></script>
  <link href="/js/danmu/barrager.css" rel="stylesheet">
<script src="/js/danmu/jquery.barrager.js"></script>
  <body>
    <!-- 判断是否为黑夜模式 -->
    <script>
      let isDark = JSON.parse(localStorage.getItem('dark')) || JSON.parse('false');

      if (isDark) {
        $(document.body).addClass('darkModel');
      }
    </script>

    <header class="header bg-color" 
  style="position: fixed; 
  left: 0; top: 0; z-index: 10;width: 100%;"
>
  <div class="header-content">
    <div class="bars">
      <div id="appDrawer" class="sidebar-image">
  <i class="fa fa-bars" aria-hidden="true" @click="showDialogDrawer"></i>
  <transition name="fade">
    <div class="drawer-box_mask" v-cloak style="display: none;" v-show="visible" @click.self="cancelDialogDrawer">
    </div>
  </transition>
  <div class="drawer-box" :class="{'active': visible}">
    <div class="drawer-box-head bg-color">
      <img class="drawer-box-head_logo" src="/medias/logo.png" alt="logo">
      <h3 class="drawer-box-head_title">😄豐Dの个人博客</h3>
      <h5 class="drawer-box-head_desc">Lmfeng Blog</h5>
    </div>
    <div class="drawer-box-content">
      <ul class="drawer-box-content_menu">
        
          <li class="drawer-box-content_item">
            <a href="/" class="menu-item-link">
              
                <i class="fa fa-home" aria-hidden="true"></i>
              
              <span>首页</span>
            </a>
          </li>
        
          <li class="drawer-box-content_item">
            <a href="/archives" class="menu-item-link">
              
                <i class="fa fa-home" aria-hidden="true"></i>
              
              <span>归档</span>
            </a>
          </li>
        
          <li class="drawer-box-content_item">
            <a href="/tags" class="menu-item-link">
              
                <i class="fa fa-tags" aria-hidden="true"></i>
              
              <span>标签</span>
            </a>
          </li>
        
          <li class="drawer-box-content_item">
            <a href="/categories" class="menu-item-link">
              
                <i class="fa fa-bookmark" aria-hidden="true"></i>
              
              <span>分类</span>
            </a>
          </li>
        
          <li class="drawer-box-content_item">
            <a href="/about" class="menu-item-link">
              
                <i class="fa fa-user" aria-hidden="true"></i>
              
              <span>关于</span>
            </a>
          </li>
        
          <li class="drawer-box-content_item">
            <a target="_blank" rel="noopener" href="https://developer.android.google.cn/" class="menu-item-link">
              
                <i class="fa fa-link" aria-hidden="true"></i>
              
              <span>友情链接</span>
            </a>
          </li>
        
        <li class="drawer-box-content_item">
          <a target="_blank" rel="noopener" href="https://github.com/melvin11112015/">
            <i class="fa fa-github" aria-hidden="true"></i>
            <span>Github</span>
          </a>
        </li>
      </ul>
    </div>
  </div>
</div>

<script>
  var body = document.body || document.documentElement || window;
  var vm = new Vue({
    el: '#appDrawer',
    data: {
      visible: false,
      top: 0,
    },
    computed: {
    },
    mounted() {
    },
    methods: {
      showDialogDrawer() {
        this.visible = true;
        // 防止页面滚动，只能让弹框滚动
        this.top = $(document).scrollTop()
        body.style.cssText = 'width: 100%; height: 100%; position: fixed; top: -' + this.top  + 'px; left: 0; overflow: hidden;';
      },
      cancelDialogDrawer() {
        this.visible = false;
        body.removeAttribute('style');
        $(document).scrollTop(this.top)
      }
    },
    created() {}
  })
</script>
    </div>
    <div class="blog-title" id="author-avatar">
      <div class="avatar">
        <img src="/medias/logo.png" alt="logo">
      </div>
      <a href="/" class="logo">😄豐Dの个人博客</a>
    </div>
    <nav class="navbar">
      <ul class="menu">
        
          <li class="menu-item">
            <a href="/" class="menu-item-link">
              
                <i class="fa fa-home" aria-hidden="true"></i>
              
              <span>首页</span>
            </a>
          </li>
        
          <li class="menu-item">
            <a href="/archives" class="menu-item-link">
              
                <i class="fa fa-archive" aria-hidden="true"></i>
              
              <span>归档</span>
            </a>
          </li>
        
          <li class="menu-item">
            <a href="/tags" class="menu-item-link">
              
                <i class="fa fa-tags" aria-hidden="true"></i>
              
              <span>标签</span>
            </a>
          </li>
        
          <li class="menu-item">
            <a href="/categories" class="menu-item-link">
              
                <i class="fa fa-bookmark" aria-hidden="true"></i>
              
              <span>分类</span>
            </a>
          </li>
        
          <li class="menu-item">
            <a href="/about" class="menu-item-link">
              
                <i class="fa fa-user" aria-hidden="true"></i>
              
              <span>关于</span>
            </a>
          </li>
        
          <li class="menu-item">
            <a target="_blank" rel="noopener" href="https://developer.android.google.cn/" class="menu-item-link">
              
                <i class="fa fa-link" aria-hidden="true"></i>
              
              <span>友情链接</span>
            </a>
          </li>
        
      </ul>
      
        <div class="dark">
  <div class="dark-content">
    <i class="fa fa-moon-o" aria-hidden="true"></i>
    <!-- <span>关灯</span> -->
  </div>
  
</div>

<script>
  $(function() {
    let isDark = JSON.parse(localStorage.getItem('dark'))  || JSON.parse('false');
    if (isDark) {
      $(".dark-content").replaceWith(
          `
          <div class='dark-content'>
            <i class="fa fa-lightbulb-o" aria-hidden="true"></i>
          </div>
          `
        );
    }
    $('.dark').click(function() {
      if ($(document.body).is('.darkModel')) {
        $(document.body).removeClass('darkModel');
        localStorage.setItem('dark', false);
        $(".dark-content").replaceWith(
          `
          <div class='dark-content'>
            <i class="fa fa-moon-o" aria-hidden="true"></i>
          </div>
          `
        );
      } else {
        $(document.body).addClass('darkModel');
        localStorage.setItem('dark', true);
        $(".dark-content").replaceWith(
          `
          <div class='dark-content'>
            <i class="fa fa-lightbulb-o" aria-hidden="true"></i>
          </div>
          `
        );
      }
    })
  })
</script>
        
      
        <div id="appSearch">
  <div class="search"  @click="showDialog()"><i class="fa fa-search" aria-hidden="true"></i></div>
  <transition name="fade">
    <div class="message-box_wrapper" style="display: none;" v-cloak v-show="dialogVisible" @click.self="cancelDialogVisible()">
      <div class="message-box animated bounceInDown">
        <div class="close" style="overflow: hidden;">
          <i class="fa fa-close" aria-hidden="true" style="float:right;" @click.self="cancelDialogVisible()"></i>
        </div>
        <h2>
          <i class="fa fa-search" aria-hidden="true"></i>
          <span class="title">本地搜索</span>
          <!-- <i class="fa fa-close" style="float:right;" aria-hidden="true" @click.self="cancelDialogVisible()"></i> -->
        </h2>
        <form class="site-search-form">
          <input type="text"
            placeholder="请输入关键字"
            id="local-search-input" 
            @click="getSearchFile()"
            class="st-search-input"
            v-model="searchInput"
          />
        </form>
        <div class="result-wrapper">
          <div id="local-search-result" class="local-search-result-cls"></div>
        </div>
      </div>
    </div>
  </transition>
</div>
<script src="/js/local_search.js"></script>
<script>
  var body = document.body || document.documentElement || window;
  var vm = new Vue({
    el: '#appSearch',
    data: {
      dialogVisible: false,
      searchInput: '',
      top: 0,
    },
    computed: {
    },
    mounted() {
    },
    methods: {
      showDialog() {
        this.dialogVisible = true;
        // 防止页面滚动，只能让弹框滚动
        this.top = $(document).scrollTop()
        body.style.cssText = 'overflow: hidden;';
      },
      getSearchFile() {
        if (!this.searchInput) {
          getSearchFile("/search.xml");
        }
      },
      cancelDialogVisible() {
        this.dialogVisible = false;
        body.removeAttribute('style');
        $(document).scrollTop(this.top)
      },
    },
    created() {}
  })
</script>
<!-- 解决刷新页面闪烁问题，可以在元素上添加display: none, 或者用vue.extend方法，详情：https://blog.csdn.net/qq_31393401/article/details/81017912 -->
<!-- 下面是搜索基本写法 -->
<!-- <script type="text/javascript" id="local.search.active">
  var inputArea = document.querySelector("#local-search-input");
  inputArea.onclick   = function(){ getSearchFile(); this.onclick = null }
  inputArea.onkeydown = function(){ if(event.keyCode == 13) return false }
</script> -->

      

    </nav>
  </div>
  
  <a target="_blank" rel="noopener" href="https://github.com/melvin11112015/" class="github-corner color-primary" aria-label="View source on GitHub"><svg width="60" height="60" viewBox="0 0 250 250" style="fill:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
  
    <div id="he-plugin-simple"></div>
    <script>
      WIDGET = {
        CONFIG: {
          "modules": "012",
          "background": 5,
          "tmpColor": "4A4A4A",
          "tmpSize": 16,
          "cityColor": "4A4A4A",
          "citySize": 16,
          "aqiSize": 16,
          "weatherIconSize": 24,
          "alertIconSize": 18,
          "padding": "10px 10px 10px 10px",
          "shadow": "1",
          "language": "auto",
          "borderRadius": 5,
          "fixed": "false",
          "vertical": "middle",
          "horizontal": "center",
          "key": "2784dd3fcb1e4f0f9a9b579bf69641f2"
        }
      }
    </script>
    <script src="https://widget.qweather.net/simple/static/js/he-simple-common.js?v=2.0"></script> 
    
</header>
    <main class="main" style="margin-top: 60px;">
      
 <!-- prismjs 代码高亮 -->
 

<div class="bg-dark-floor" style="position: fixed;left: 0;top: 0;width: 100%;height: 100%;z-index: -1;"></div>
<div id="appBgSwiper" style="position: fixed;left: 0;top: 0;width: 100%;height: 100%;z-index: -2;" :style="{'background-color': bgColor ? bgColor : 'transparent'}">
    <transition-group tag="ul" :name="names">
        <li v-for='(image,index) in img' :key='index' v-show="index === mark" class="bg-swiper-box">
            <img :src="image" class="bg-swiper-img">
        </li>
    </transition-group>
</div>
<script>
    var vm = new Vue({
        el: '#appBgSwiper',
        data: {
            names: '' || 'fade' || 'fade', // translate-fade fade
            mark: 0,
            img: [],
            bgColor: '',
            time: null
        },
        methods: {   //添加方法
            change(i, m) {
                if (i > m) {
                    // this.names = 'fade';
                } else if (i < m) {
                    // this.names = 'fade';
                } else {
                    return;
                }
                this.mark = i;
            },
            prev() {
                // this.names = 'fade';
                this.mark--;
                if (this.mark === -1) {
                    this.mark = 3;
                    return
                }
            },
            next() {
                // this.names = 'fade';
                this.mark++;
                if (this.mark === this.img.length) {
                    this.mark = 0;
                    return
                }
            },
            autoPlay() {
                // this.names = 'fade';
                this.mark++;
                if (this.mark === this.img.length) {
                    this.mark = 0;
                    return
                }
            },
            play() {
                let bgImgDelay = '' || '180000'
                let delay = parseInt(bgImgDelay) || 180000;
                this.time = setInterval(this.autoPlay, delay);
            },
            enter() {
                clearInterval(this.time);
            },
            leave() {
                this.play();
            }
        },
        created() {
            this.play()
        },
        beforeDestroy() {
            clearInterval(this.time);
        },
        mounted() {
            let prop = ''|| '';
            let isImg = prop.includes('.bmp') || prop.includes('.jpg') || prop.includes('.png') || prop.includes('.tif') || prop.includes('.gif') || prop.includes('.pcx') || prop.includes('.tga') || prop.includes('.exif') || prop.includes('.fpx') || prop.includes('.psd') || prop.includes('.cdr') || prop.includes('.pcd') || prop.includes('.dxf') || prop.includes('.ufo') || prop.includes('.eps') || prop.includes('.ai') || prop.includes('.raw') || prop.includes('.WMF') || prop.includes('.webp') || prop.includes('.jpeg')
            if (isImg) {
                let img = prop.split(',');
                let configRoot = '/'
                let arrImg = [];
                img.forEach(el => {
                    var Expression=/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/;
			        var objExp = new RegExp(Expression);

                    if(objExp.test(el)) {
                        // http or https
                        arrImg.push(el);
                    } else {
                        // 非http or https开头
                        // 本地文件
                        let firstStr = el.charAt(0);
                        if (firstStr == '/') {
                            el = el.substr(1); // 删除第一个字符 '/',因为 configRoot最后一个字符为 /
                        }
                        el = configRoot + el;
                        arrImg.push(el);
                    }
                })
                this.img = arrImg;
            } else {
                this.bgColor = prop;
            }
        }
    })
</script>

<style>
    .bg-swiper-box {
        position: absolute;
        display: block;
        width: 100%;
        height: 100%;
    }
    .bg-swiper-img {
        object-fit: cover;
        width: 100%;
        height: 100%;
    }
</style>



<div class="post-detail-header lazyload" id="thumbnail_canvas" data-original="/medias/6.jpg" style="background-repeat: no-repeat; background-size: cover; 
  background-position: center center;position: relative;">
  <div class="post-detail-header-mask"></div>
  <canvas id="header_canvas"style="position:absolute;bottom:0"></canvas>
  
    <div class="title-box">
      
        <span class="title" id="post-detail-header-title"></span>
        <script src="https://cdn.jsdelivr.net/npm/typed.js@2.0.11"></script>
          <script>
            var typed = new Typed("#post-detail-header-title", {
              strings: ['使用hexo+github搭建免费个人博客详细教程'],
              startDelay: 100,
              typeSpeed: 100,
              loop: false,
              backSpeed: 50,
              showCursor: false
            });
          </script>
        
    </div>
  
  
  
    <script src="/js/bubble/bubble.js"></script>
  
</div>


<div class="row justify-position">
  <div class="main-content">
    <article class="post post-detail">
      
      
      <div class="post-meta">
        <i class="fa fa-clock-o" aria-hidden="true"></i>
        <span class="post-time">2015-11-01</span>
      </div>
      
      <div class="post-tags-categories">
        
        <div class="tags">
          <i class="iconfont icontag"></i>
          
            <a href="/tags/Hexo/" class="">
              Hexo
            </a>
          
        </div>
        
        
        <div class="categories">
          <i class="iconfont iconbookmark1"></i>
          
            <a href="/categories/Hexo/" class="">
              Hexo
            </a>
          
        </div>
        
      </div>
      <div class="post-content">
        <h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>体验更加排版请访问原文链接：<a target="_blank" rel="noopener" href="http://blog.liuxianan.com/build-blog-website-by-hexo-github.html">http://blog.liuxianan.com/build-blog-website-by-hexo-github.html</a></p>
<p>使用github pages服务搭建博客的好处有：</p>
<ol>
<li> 全是静态文件，访问速度快；</li>
<li> 免费方便，不用花一分钱就可以搭建一个自由的个人博客，不需要服务器不需要后台；</li>
<li> 可以随意绑定自己的域名，不仔细看的话根本看不出来你的网站是基于github的；</li>
<li> 数据绝对安全，基于github的版本管理，想恢复到哪个历史版本都行；</li>
<li> 博客内容可以轻松打包、转移、发布到其它平台；</li>
<li> 等等；</li>
</ol>
<h2 id="1-1-准备工作"><a href="#1-1-准备工作" class="headerlink" title="1.1. 准备工作"></a>1.1. 准备工作</h2><p>在开始一切之前，你必须已经：</p>
<ul>
<li>  有一个github账号，没有的话去注册一个；</li>
<li>  安装了node.js、npm，并了解相关基础知识；</li>
<li>  安装了git for windows（或者其它git客户端）</li>
</ul>
<p>本文所使用的环境：</p>
<ul>
<li>  Windows8.1</li>
<li>  <a href="mailto:&#110;&#x6f;&#100;&#x65;&#x2e;&#x6a;&#115;&#x40;&#x35;&#46;&#x35;&#46;&#x30;">&#110;&#x6f;&#100;&#x65;&#x2e;&#x6a;&#115;&#x40;&#x35;&#46;&#x35;&#46;&#x30;</a></li>
<li>  <a href="mailto:&#x67;&#105;&#x74;&#x40;&#x31;&#x2e;&#x39;&#x2e;&#50;">&#x67;&#105;&#x74;&#x40;&#x31;&#x2e;&#x39;&#x2e;&#50;</a></li>
<li>  <a href="mailto:&#104;&#101;&#x78;&#111;&#64;&#51;&#46;&#x32;&#x2e;&#x32;">&#104;&#101;&#x78;&#111;&#64;&#51;&#46;&#x32;&#x2e;&#x32;</a></li>
</ul>
<h1 id="搭建github博客"><a href="#搭建github博客" class="headerlink" title="搭建github博客"></a>搭建github博客</h1><h2 id="2-1-创建仓库"><a href="#2-1-创建仓库" class="headerlink" title="2.1. 创建仓库"></a>2.1. 创建仓库</h2><p>新建一个名为<code>你的用户名.github.io</code>的仓库，比如说，如果你的github用户名是test，那么你就新建<code>test.github.io</code>的仓库（必须是你的用户名，其它名称无效），将来你的网站访问地址就是 <a target="_blank" rel="noopener" href="http://test.github.io/">http://test.github.io</a> 了，是不是很方便？</p>
<p>由此可见，每一个github账户最多只能创建一个这样可以直接使用域名访问的仓库。</p>
<p>几个注意的地方：</p>
<ol>
<li> 注册的邮箱一定要验证，否则不会成功；</li>
<li> 仓库名字必须是：<code>username.github.io</code>，其中<code>username</code>是你的用户名；</li>
<li> 仓库创建成功不会立即生效，需要过一段时间，大概10-30分钟，或者更久，我的等了半个小时才生效；</li>
</ol>
<p>创建成功后，默认会在你这个仓库里生成一些示例页面，以后你的网站所有代码都是放在这个仓库里啦。</p>
<h2 id="2-2-绑定域名"><a href="#2-2-绑定域名" class="headerlink" title="2.2. 绑定域名"></a>2.2. 绑定域名</h2><p>当然，你不绑定域名肯定也是可以的，就用默认的 <code>xxx.github.io</code> 来访问，如果你想更个性一点，想拥有一个属于自己的域名，那也是OK的。</p>
<p>首先你要注册一个域名，域名注册以前总是推荐去<code>godaddy</code>，现在觉得其实国内的阿里云也挺不错的，价格也不贵，毕竟是大公司，放心！</p>
<p>绑定域名分2种情况：带www和不带www的。</p>
<p>域名配置最常见有2种方式，CNAME和A记录，CNAME填写域名，A记录填写IP，由于不带www方式只能采用A记录，所以必须先ping一下<code>你的用户名.github.io</code>的IP，然后到你的域名DNS设置页，将A记录指向你ping出来的IP，将CNAME指向<code>你的用户名.github.io</code>，这样可以保证无论是否添加www都可以访问，如下：</p>
<p>然后到你的github项目根目录新建一个名为CNAME的文件（无后缀），里面填写你的域名，加不加www看你自己喜好，因为经测试：</p>
<ul>
<li>  如果你填写的是没有www的，比如 mygit.me，那么无论是访问 <a target="_blank" rel="noopener" href="http://www.mygit.me/">http://www.mygit.me</a> 还是 <a target="_blank" rel="noopener" href="http://mygit.me/">http://mygit.me</a> ，都会自动跳转到 <a target="_blank" rel="noopener" href="http://mygit.me/">http://mygit.me</a></li>
<li>  如果你填写的是带www的，比如 <a target="_blank" rel="noopener" href="http://www.mygit.me/">www.mygit.me</a> ，那么无论是访问 <a target="_blank" rel="noopener" href="http://www.mygit.me/">http://www.mygit.me</a> 还是 <a target="_blank" rel="noopener" href="http://mygit.me/">http://mygit.me</a> ，都会自动跳转到 <a target="_blank" rel="noopener" href="http://www.mygit.me/">http://www.mygit.me</a></li>
<li>  如果你填写的是其它子域名，比如 abc.mygit.me，那么访问 <a target="_blank" rel="noopener" href="http://abc.mygit.me/">http://abc.mygit.me</a> 没问题，但是访问 <a target="_blank" rel="noopener" href="http://mygit.me/">http://mygit.me</a> ，不会自动跳转到 <a target="_blank" rel="noopener" href="http://abc.mygit.me/">http://abc.mygit.me</a></li>
</ul>
<p>另外说一句，在你绑定了新域名之后，原来的<code>你的用户名.github.io</code>并没有失效，而是会自动跳转到你的新域名。</p>
<h1 id="配置SSH-key"><a href="#配置SSH-key" class="headerlink" title="配置SSH key"></a>配置SSH key</h1><p>为什么要配置这个呢？因为你提交代码肯定要拥有你的github权限才可以，但是直接使用用户名和密码太不安全了，所以我们使用ssh key来解决本地和服务器的连接问题。</p>
<pre><code>$ cd ~/. ssh #检查本机已存在的ssh密钥
</code></pre>
<p>如果提示：No such file or directory 说明你是第一次使用git。</p>
<pre><code>ssh-keygen -t rsa -C &quot;邮件地址&quot;
</code></pre>
<p>然后连续3次回车，最终会生成一个文件在用户目录下，打开用户目录，找到<code>.ssh\id_rsa.pub</code>文件，记事本打开并复制里面的内容，打开你的github主页，进入个人设置 -&gt; SSH and GPG keys -&gt; New SSH key：</p>
<p>将刚复制的内容粘贴到key那里，title随便填，保存。</p>
<h2 id="3-1-测试是否成功"><a href="#3-1-测试是否成功" class="headerlink" title="3.1. 测试是否成功"></a>3.1. 测试是否成功</h2><pre><code>$ ssh -T git@github.com # 注意邮箱地址不用改
</code></pre>
<p>如果提示<code>Are you sure you want to continue connecting (yes/no)?</code>，输入yes，然后会看到：</p>
<blockquote>
<p>Hi liuxianan! You’ve successfully authenticated, but GitHub does not provide shell access.</p>
</blockquote>
<p>看到这个信息说明SSH已配置成功！</p>
<p>此时你还需要配置：</p>
<pre><code>$ git config --global user.name &quot;liuxianan&quot;// 你的github用户名，非昵称
$ git config --global user.email  &quot;xxx@qq.com&quot;// 填写你的github注册邮箱
</code></pre>
<p>具体这个配置是干嘛的我没仔细深究。</p>
<h1 id="使用hexo写博客"><a href="#使用hexo写博客" class="headerlink" title="使用hexo写博客"></a>使用hexo写博客</h1><h2 id="4-1-hexo简介"><a href="#4-1-hexo简介" class="headerlink" title="4.1. hexo简介"></a>4.1. hexo简介</h2><p>Hexo是一个简单、快速、强大的基于 Github Pages 的博客发布工具，支持Markdown格式，有众多优秀插件和主题。</p>
<p>官网： <a target="_blank" rel="noopener" href="http://hexo.io/">http://hexo.io</a><br>github: <a target="_blank" rel="noopener" href="https://github.com/hexojs/hexo">https://github.com/hexojs/hexo</a></p>
<h2 id="4-2-原理"><a href="#4-2-原理" class="headerlink" title="4.2. 原理"></a>4.2. 原理</h2><p>由于github pages存放的都是静态文件，博客存放的不只是文章内容，还有文章列表、分类、标签、翻页等动态内容，假如每次写完一篇文章都要手动更新博文目录和相关链接信息，相信谁都会疯掉，所以hexo所做的就是将这些md文件都放在本地，每次写完文章后调用写好的命令来批量完成相关页面的生成，然后再将有改动的页面提交到github。</p>
<h2 id="4-3-注意事项"><a href="#4-3-注意事项" class="headerlink" title="4.3. 注意事项"></a>4.3. 注意事项</h2><p>安装之前先来说几个注意事项：</p>
<ol>
<li> 很多命令既可以用Windows的cmd来完成，也可以使用git bash来完成，但是部分命令会有一些问题，为避免不必要的问题，建议全部使用git bash来执行；</li>
<li> hexo不同版本差别比较大，网上很多文章的配置信息都是基于2.x的，所以注意不要被误导；</li>
<li> hexo有2种<code>_config.yml</code>文件，一个是根目录下的全局的<code>_config.yml</code>，一个是各个<code>theme</code>下的；</li>
</ol>
<h2 id="4-4-安装"><a href="#4-4-安装" class="headerlink" title="4.4. 安装"></a>4.4. 安装</h2><pre><code>$ npm install -g hexo
</code></pre>
<h2 id="4-5-初始化"><a href="#4-5-初始化" class="headerlink" title="4.5. 初始化"></a>4.5. 初始化</h2><p>在电脑的某个地方新建一个名为hexo的文件夹（名字可以随便取），比如我的是<code>F:\Workspaces\hexo</code>，由于这个文件夹将来就作为你存放代码的地方，所以最好不要随便放。</p>
<pre><code>$ cd /f/Workspaces/hexo/
$ hexo init
</code></pre>
<p>hexo会自动下载一些文件到这个目录，包括node_modules，目录结构如下图：</p>
<pre><code>$ hexo g # 生成
$ hexo s # 启动服务
</code></pre>
<p>执行以上命令之后，hexo就会在public文件夹生成相关html文件，这些文件将来都是要提交到github去的：</p>
<p><code>hexo s</code>是开启本地预览服务，打开浏览器访问 <a target="_blank" rel="noopener" href="http://localhost:4000/">http://localhost:4000</a> 即可看到内容，很多人会碰到浏览器一直在转圈但是就是加载不出来的问题，一般情况下是因为端口占用的缘故，因为4000这个端口太常见了，解决端口冲突问题请参考这篇文章：</p>
<p><a target="_blank" rel="noopener" href="http://blog.liuxianan.com/windows-port-bind.html">http://blog.liuxianan.com/windows-port-bind.html</a></p>
<p>第一次初始化的时候hexo已经帮我们写了一篇名为 Hello World 的文章，默认的主题比较丑，打开时就是这个样子：</p>
<h2 id="4-6-修改主题"><a href="#4-6-修改主题" class="headerlink" title="4.6. 修改主题"></a>4.6. 修改主题</h2><p>既然默认主题很丑，那我们别的不做，首先来替换一个好看点的主题。这是 <a target="_blank" rel="noopener" href="https://hexo.io/themes/">官方主题</a>。</p>
<p>个人比较喜欢的2个主题：<a target="_blank" rel="noopener" href="https://github.com/pinggod/hexo-theme-jekyll">hexo-theme-jekyll</a> 和 <a target="_blank" rel="noopener" href="https://github.com/litten/hexo-theme-yilia">hexo-theme-yilia</a>。</p>
<p>首先下载这个主题：</p>
<pre><code>$ cd /f/Workspaces/hexo/
$ git clone https://github.com/litten/hexo-theme-yilia.git themes/yilia
</code></pre>
<p>下载后的主题都在这里：</p>
<p>修改<code>_config.yml</code>中的<code>theme: landscape</code>改为<code>theme: yilia</code>，然后重新执行<code>hexo g</code>来重新生成。</p>
<p>如果出现一些莫名其妙的问题，可以先执行<code>hexo clean</code>来清理一下public的内容，然后再来重新生成和发布。</p>
<h2 id="4-7-上传之前"><a href="#4-7-上传之前" class="headerlink" title="4.7. 上传之前"></a>4.7. 上传之前</h2><p>在上传代码到github之前，一定要记得先把你以前所有代码下载下来（虽然github有版本管理，但备份一下总是好的），因为从hexo提交代码时会把你以前的所有代码都删掉。</p>
<h2 id="4-8-上传到github"><a href="#4-8-上传到github" class="headerlink" title="4.8. 上传到github"></a>4.8. 上传到github</h2><p>如果你一切都配置好了，发布上传很容易，一句<code>hexo d</code>就搞定，当然关键还是你要把所有东西配置好。</p>
<p>首先，<code>ssh key</code>肯定要配置好。</p>
<p>其次，配置<code>_config.yml</code>中有关deploy的部分：</p>
<p>正确写法：</p>
<pre><code>deploy:
  type: git
  repository: git@github.com:liuxianan/liuxianan.github.io.git
  branch: master
</code></pre>
<p>错误写法：</p>
<pre><code>deploy:
  type: github
  repository: https://github.com/liuxianan/liuxianan.github.io.git
  branch: master
</code></pre>
<p>后面一种写法是hexo2.x的写法，现在已经不行了，无论是哪种写法，此时直接执行<code>hexo d</code>的话一般会报如下错误：</p>
<pre><code>Deployer not found: github 或者 Deployer not found: git
</code></pre>
<p>原因是还需要安装一个插件：</p>
<pre><code>npm install hexo-deployer-git --save
</code></pre>
<p>其它命令不确定，部署这个命令一定要用git bash，否则会提示<code>Permission denied (publickey).</code></p>
<p>打开你的git bash，输入<code>hexo d</code>就会将本次有改动的代码全部提交，没有改动的不会：</p>
<h2 id="4-9-保留CNAME、README-md等文件"><a href="#4-9-保留CNAME、README-md等文件" class="headerlink" title="4.9. 保留CNAME、README.md等文件"></a>4.9. 保留CNAME、README.md等文件</h2><p>提交之后网页上一看，发现以前其它代码都没了，此时不要慌，一些非md文件可以把他们放到source文件夹下，这里的所有文件都会原样复制（除了md文件）到public目录的：</p>
<p>由于hexo默认会把所有md文件都转换成html，包括README.md，所有需要每次生成之后、上传之前，手动将README.md复制到public目录，并删除README.html。</p>
<h2 id="4-10-常用hexo命令"><a href="#4-10-常用hexo命令" class="headerlink" title="4.10. 常用hexo命令"></a>4.10. 常用hexo命令</h2><p>常见命令</p>
<pre><code>hexo new &quot;postName&quot; #新建文章
hexo new page &quot;pageName&quot; #新建页面
hexo generate #生成静态页面至public目录
hexo server #开启预览访问端口（默认端口4000，&#39;ctrl + c&#39;关闭server）
hexo deploy #部署到GitHub
hexo help  # 查看帮助
hexo version  #查看Hexo的版本
</code></pre>
<p>缩写：</p>
<pre><code>hexo n == hexo new
hexo g == hexo generate
hexo s == hexo server
hexo d == hexo deploy
</code></pre>
<p>组合命令：</p>
<pre><code>hexo s -g #生成并本地预览
hexo d -g #生成并上传
</code></pre>
<h2 id="4-11-config-yml"><a href="#4-11-config-yml" class="headerlink" title="4.11. _config.yml"></a>4.11. _config.yml</h2><p>这里面都是一些全局配置，每个参数的意思都比较简单明了，所以就不作详细介绍了。</p>
<p>需要特别注意的地方是，冒号后面必须有一个空格，否则可能会出问题。</p>
<h2 id="4-12-写博客"><a href="#4-12-写博客" class="headerlink" title="4.12. 写博客"></a>4.12. 写博客</h2><p>定位到我们的hexo根目录，执行命令：</p>
<pre><code>hexo new &#39;my-first-blog&#39;
</code></pre>
<p>hexo会帮我们在<code>_posts</code>下生成相关md文件：</p>
<p>我们只需要打开这个文件就可以开始写博客了，默认生成如下内容：</p>
<p>当然你也可以直接自己新建md文件，用这个命令的好处是帮我们自动生成了时间。</p>
<p>一般完整格式如下：</p>
<pre><code>---
title: postName #文章页面上的显示名称，一般是中文
date: 2013-12-02 15:30:16 #文章生成时间，一般不改，当然也可以任意修改
categories: 默认分类 #分类
tags: [tag1,tag2,tag3] #文章标签，可空，多标签请用格式，注意:后面有个空格
description: 附加一段文章摘要，字数最好在140字以内，会出现在meta的description里面
---

以下是正文

</code></pre>
<p>那么<code>hexo new page &#39;postName&#39;</code>命令和<code>hexo new &#39;postName&#39;</code>有什么区别呢？</p>
<pre><code>hexo new page &quot;my-second-blog&quot;
</code></pre>
<p>生成如下：</p>
<p>最终部署时生成：<code>hexo\public\my-second-blog\index.html</code>，但是它不会作为文章出现在博文目录。</p>
<h3 id="4-12-1-写博客工具"><a href="#4-12-1-写博客工具" class="headerlink" title="4.12.1. 写博客工具"></a>4.12.1. 写博客工具</h3><p>那么用什么工具写博客呢？这个我还没去找，以前自己使用editor.md简单弄了个，大家有好用的hexo写博客工具可以推荐个。</p>
<h3 id="4-12-2-如何让博文列表不显示全部内容"><a href="#4-12-2-如何让博文列表不显示全部内容" class="headerlink" title="4.12.2. 如何让博文列表不显示全部内容"></a>4.12.2. 如何让博文列表不显示全部内容</h3><p>默认情况下，生成的博文目录会显示全部的文章内容，如何设置文章摘要的长度呢？</p>
<p>答案是在合适的位置加上<code>&lt;!--more--&gt;</code>即可，例如：</p>
<pre><code># 前言

使用github pages服务搭建博客的好处有：

1. 全是静态文件，访问速度快；
2. 免费方便，不用花一分钱就可以搭建一个自由的个人博客，不需要服务器不需要后台；
3. 可以随意绑定自己的域名，不仔细看的话根本看不出来你的网站是基于github的；

&lt;!--more--&gt;

4. 数据绝对安全，基于github的版本管理，想恢复到哪个历史版本都行；
5. 博客内容可以轻松打包、转移、发布到其它平台；
6. 等等；
</code></pre>

      </div>
      
    </article>
    <!-- 上一篇文章和下一篇文章 -->
    
      
<div class="post-nav">



  
  <div class="post-nav-prev post-nav-item">
    <div class="post-nav-img lazyload" data-original="/medias/11.jpg" style="background-size: cover; 
      background-position: center center;">
    </div>
    <a href="/2015/11/02/2102/" class="post-nav-link">
      <div class="title">
        <i class="fa fa-angle-left"></i> 上一篇:
        <div>Hexo部署报错ERROR Deployer not found git</div>
      </div>
      
      <!-- <div class="content">
        输入命令即可安装插件即可
npm install --save hexo-deployer-git


      </div> -->
    </a>
  </div>



  
  <div class="post-nav-next post-nav-item">
    <div class="post-nav-img lazyload" data-original="/medias/7.jpg" style="background-size: cover; 
      background-position: center center;">
    </div>
    <a href="/2015/01/01/hello-world/" class="post-nav-link">
      <div class="title">
        下一篇: <i class="fa fa-angle-right"></i>
        <div>Hello World</div>
      </div>
      <!-- <div class="content">
        Welcome to Hexo! This is your very first post. Check documen
      </div> -->
    </a>
  </div>

</div>

    
    

    <!-- 打赏 -->
    

    <!-- 分享 -->
    
    
    <!-- 评论 -->
      
        <div id="myComment">
          
        </div>
      
  </div>

  
    <div class="toc-aside">
      <div class="toc-main">
        <div class="toc-aside-title">
          <i class="fa fa-list-ul" aria-hidden="true"></i><span>本文目录</span>
          <div class="toc-open-close">本文目录</div>
        </div>
        <div class="toc-content">
          <link href="/js/tocbot/tocbot.css" rel="stylesheet">
<script src="/js/tocbot/tocbot.min.js"></script>
<div class="toc"></div>

<script>
  if ($('.toc').length > 0) {
    var headerEl = 'h2, h3, h4',  //headers 
      content = '.post-detail',//文章容器
      idArr = {};  //标题数组以确定是否增加索引id
      //add #id

    $(content).children(headerEl).each(function () {
      //去除空格以及多余标点
      var headerId = $(this).text().replace(/[\s|\~|`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\_|\+|\=|\||\|\[|\]|\{|\}|\;|\:|\"|\'|\,|\<|\.|\>|\/|\?|\：|\，|\。]/g, '');

      headerId = headerId.toLowerCase();
      if (idArr[headerId]) {
        //id已经存在
        $(this).attr('id', headerId + '-' + idArr[headerId]);
        idArr[headerId]++;
      }
      else {
        //id未存在
        idArr[headerId] = 1;
        $(this).attr('id', headerId);
      }
    });

    tocbot.init({
      // Where to render the table of contents.
      tocSelector: '.toc',
      // Where to grab the headings to build the table of contents.
      contentSelector: content,
      // Which headings to grab inside of the contentSelector element.
      headingSelector: headerEl,
      scrollSmooth: true,
      scrollSmoothOffset: -80,
      headingsOffset: 130,
      positionFixedSelector: '.toc-main',
      positionFixedClass: 'is-position-fixed',
      fixedSidebarOffset: 'auto',
    });
  }

</script>

<style>
.is-position-fixed {
  position:fixed !important;
  top: 64px;
}
.toc-main ul {
  counter-reset: show-list;
}
.toc-main ul li::before {
  content: counter(item)".";
  display: block;
  position: absolute;
  left: 12px;
  top:0;
}
.toc > .toc-list {
  padding-left: 35px;
}
.toc>.toc-list li {
  list-style: decimal;
}
.toc-list {
  padding-left: 25px;
}
</style>
        </div>
      </div>
    </div>

    

    <script>
      let openOrCloseBtn = $('.toc-aside .toc-aside-title .toc-open-close');
      let open = eval('' || 'true');
      openOrCloseBtn.click(function() {
        if (open === true) {
          $(".toc-aside").css({'width': 0, 'padding': 0});
          $(".toc-content").css({'width': 0});
          $(".toc-aside-title span, .toc-aside-title i").css({'display': 'none'});
          $(".main-content").css({'width': '75%', 'margin': '10px auto'});
          open = false;
        } else {
          $(".toc-aside").css({'width': '300px', 'padding': '0 10px'});
          $(".toc-content").css({'width': '300px'});
          $(".toc-aside-title span, .toc-aside-title i").css({'display': 'inline-block'});
          $(".main-content").css({'width': '65%', 'margin-right': '10px', 'margin-left': 'calc(35% - 350px)'});
          open = true;
        }
      });
    </script>
  
</div>


    </main>
    <div class="footer bg-color">
  <div class="footer-main">
<!--    <div class="link">
      <a target="_blank" rel="noopener" href="https://github.com/yuang01/hexo-theme-bamboo">
        <i class="fa fa-github" aria-hidden="true"></i>
      </a>
      <a href="mailto:1730241541@qq.com">
        <i class="fa fa-envelope-o" aria-hidden="true"></i>
      </a>
      <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=1730241541">
        <i class="fa fa-qq" aria-hidden="true"></i>
      </a>
      <a href="/atom.xml" target="_blank">
        <i class="fa fa-rss" aria-hidden="true"></i>
      </a>
    </div>
-->
    <div class="footer-copyright">
      Copyright © 2015 - 2021 <a href="/about">Melvin</a> | Powered by <a target="_blank" rel="noopener" href="https://hexo.io/zh-cn/docs/">Hexo</a> | Theme <a target="_blank" rel="noopener" href="https://github.com/yuang01/theme">Bamboo</a> 
    </div>
    
  </div>
</div>


    
      <div class="goTop top-btn-color border-color">
  <i class="fa fa-arrow-up" aria-hidden="true"></i>
</div>
<script src="/js/goTop.js"></script>
    

    

    <!-- 图片放大 -->
    
      <script src="/js/fancybox/jquery.fancybox.min.js"></script>
    

    <script src="/js/wrapImage.js"></script>
    
    <!-- 爱心点击 -->
    
      
        <canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 999; pointer-events: none;" ></canvas>
        <script src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script>
        <script src="/js/cursor/explosion.min.js"></script>
      
    

    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>

    
    <script type="text/javascript" size="100" alpha='0.4' zIndex="-1" src="/js/ribbon.min.js"></script>
    
      <script src="/js/aos/aos.js"></script>
      <script>
        // https://github.com/michalsnik/aos
        const themeOffset = parseInt('120') || 120;
        const themeDelay = parseInt('0')|| 0;
        const themeDuration = parseInt('400') || 400;
        const themeEasing = 'ease' || 'ease';
        const themeOnce = eval('true') || false;
        const themeMirror = eval('false') || false;
        const themeAnchorPlacement = 'top-bottom' || 'top-bottom';
        AOS.init({
          // Global settings:
          disable: false, // accepts following values: 'phone', 'tablet', 'mobile', boolean, expression or function
          startEvent: 'DOMContentLoaded', // name of the event dispatched on the document, that AOS should initialize on
          initClassName: 'aos-init', // class applied after initialization
          animatedClassName: 'aos-animate', // class applied on animation
          useClassNames: false, // if true, will add content of `data-aos` as classes on scroll
          disableMutationObserver: false, // disables automatic mutations' detections (advanced)
          debounceDelay: 50, // the delay on debounce used while resizing window (advanced)
          throttleDelay: 99, // the delay on throttle used while scrolling the page (advanced)

          // Settings that can be overridden on per-element basis, by `data-aos-*` attributes:
          offset: themeOffset, // offset (in px) from the original trigger point
          delay: themeDelay, // values from 0 to 3000, with step 50ms
          duration: themeDuration, // values from 0 to 3000, with step 50ms
          easing: themeEasing, // default easing for AOS animations
          once: themeOnce, // whether animation should happen only once - while scrolling down
          mirror: themeMirror, // whether elements should animate out while scrolling past them
          anchorPlacement: themeAnchorPlacement, // defines which position of the element regarding to window should trigger the animation

        });
      </script>
    

    
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/v-plugs-ayu/lib/ayu.css">
<script src="https://cdn.jsdelivr.net/npm/v-plugs-ayu/lib/ayu.umd.min.js"></script>
<div id="appCopy">
</div>
<script>
  var vm = new Vue({
    el: '#appCopy',
    data: {
    },
    computed: {
    },
    mounted() {
      const that = this;
      //  监听 ctrl + c事件  
      $(document).unbind('keypress').bind('keypress', function (e) {
        if (e.ctrlKey && e.keyCode == 67) {
          doSomething();
          // 返回false, 防止重复触发copy事件  
          return false;
        }
      })

      // 鼠标右键的复制事件  
      $(document).unbind('copy').bind('copy', function (e) {
        doSomething();
        // console.log('右键复制 监听成功');
      });

      function doSomething() {
        that.$notify({
          title: "成功",
          content: "代码已复制，请遵守相关授权协议。",
          type: 'success'
        })
        // console.log('ctrl + c 监听成功');  
      }
    },
    methods: {
    },
    created() { }
  })
</script>
    

    <!-- 输入框打字特效 -->
    
      <script src="/js/activate-power-mode.js"></script>
      <script>
          POWERMODE.colorful = true;  // 打开随机颜色特效
          POWERMODE.shake = false;    // 关闭输入框抖动
          document.body.addEventListener('input', POWERMODE);//监听打字事件
      </script>
    

    <!-- markdown代码一键复制功能 -->
    <script src="/js/clipboard/clipboard.min.js"></script>
    <script>
      !function (e, t, a) {
        var copy = '复制';
        /* code */
        var initCopyCode = function(){
          var copyHtml = '';
          copyHtml += '<button class="btn-copy" data-clipboard-snippet="" style="position:absolute;top:0;right:0;z-index:1;">';
          copyHtml += '<i class="fa fa-copy"></i><span>' + copy + '</span>';
          copyHtml += '</button>';
          $(".post-detail pre").not('.gutter pre').wrap("<div class='codeBox' style='position:relative;width:100%;'></div>")
          $(".post-detail pre").not('.gutter pre').before(copyHtml);
          new ClipboardJS('.btn-copy', {
              target: function(trigger) {
                  return trigger.nextElementSibling;
              }
          });
        }
        initCopyCode();
      }(window, document);
    </script>

    <script src="/js/lazyload/lazyload@1.9.1.js"></script>
    <script>
      $(function() {
        $("div.lazyload, img.lazyload, a.lazyload").lazyload(
            {
                effect: "fadeIn",
                placeholder: "https://img10.360buyimg.com/ddimg/jfs/t1/159345/8/2271/222193/5ff7b36fEe49f5663/a95287c20385127f.gif"    //图片未加载出来时显示的占位图
            }
        );
    });
    </script>
    
    <script src="/js/app.js"></script>
  </body>
</html>